/**
 * 
 */
package gemini.castor.ui.client.page.widget;

import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.TextBox;

/**
 * The abstract field for all standard fields in FKR project.
 */
public abstract class GmnAbstractField extends TextBox {
	
	public GmnAbstractField() {
		super();
		
		addKeyPressHandler(new KeyPressHandler() {
			
			@Override
			public void onKeyPress(KeyPressEvent event) {
				int key = event.getCharCode();
				if (event.isControlKeyDown()) {
					return;
				}
				
				if (!isSystemKey(key) && !isAllowedChar(key)) {
					cancelKey();
				}
			}
		});
		
		addKeyUpHandler(new KeyUpHandler() {
			
			@Override
			public void onKeyUp(KeyUpEvent event) {
				checkValue();
			}
		});
		
		addMouseDownHandler(new MouseDownHandler() {
			
			@Override
			public void onMouseDown(MouseDownEvent event) {
				if(event.getNativeButton() == NativeEvent.BUTTON_LEFT) {
					checkValue();
				}
			}
		});
		
		addValueChangeHandler(new ValueChangeHandler<String>() {
			
			@Override
			public void onValueChange(ValueChangeEvent<String> event) {
				checkValue();
			}
		});
		
	}
	
	protected abstract boolean isAllowedChar(int c);
	
	/*
	 * In case user copy / paste invalid value into control, this handler
	 * prevent this situation by removing all invalid characters.
	 */
	private void checkValue() {
		String s = getValue();
		boolean changed = false;
		String replace = s;
		
		int length = replace.length();
		for (int i = 0; i < length; i++) {
			if(!isAllowedChar(replace.charAt(i))) {
				s = s.replace(replace.charAt(i) + "", "");
				changed = true;
			}
		}
		if (changed) {
			setValue(s);
		}
	}
	
	private boolean isSystemKey(int key) {
		boolean result = false;
		if (key == 0
				 || key == KeyCodes.KEY_DELETE
				 || key == KeyCodes.KEY_HOME
				 || key == KeyCodes.KEY_END
				 || key == KeyCodes.KEY_LEFT
				 || key == KeyCodes.KEY_RIGHT
				 || key == KeyCodes.KEY_BACKSPACE
				 || key == KeyCodes.KEY_SHIFT
				 || key == KeyCodes.KEY_TAB
				 || key == KeyCodes.KEY_ALT
				 || key == KeyCodes.KEY_CTRL) {
			result = true;
		}
			
		return result;
	}
}
